package com.tony.util.utils;

import cn.hutool.core.util.RandomUtil;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicReference;

public class AtomicIdGenerator {
    private static long timestampBit = 41;
    private static long sequenceSecret = (1L << timestampBit) -1;

    private static AtomicReference<Variant> atomicReference = new AtomicReference<>(new Variant());

    public static long generator() {
        while(true){
            Variant variant = atomicReference.get();

            long sequence =  variant.sequence;
            long timeMillis = System.currentTimeMillis();
            if(variant.lastTimestamp == timeMillis){
                sequence ++ ;
            }else{
                sequence = 1;
            }

            long id = (sequence << timestampBit) + timeMillis;

            Variant newVariant = new Variant();
            newVariant.lastTimestamp = timeMillis;
            newVariant.sequence = sequence;

            if(atomicReference.compareAndSet(variant,newVariant)){
                System.out.println("生成时的时间戳\t"+timeMillis);
                System.out.println("生成时的序列号\t"+sequence);
                return id;
            }
        }
    }

    private static String generatorYMDHMSS(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
    }

    public static String generatorCompanyNo(){
        StringBuffer sb = new StringBuffer();
        sb.append(generatorYMDHMSS());
        sb.append(RandomUtil.randomNumbers(6));
        return sb.toString();
    }

    public static String generatorOrderNo(){
        StringBuffer sb = new StringBuffer();
        sb.append(generatorYMDHMSS());
        sb.append(generator());
        return sb.toString();
    }

    public static String generatorTaskNo(){
        StringBuffer sb = new StringBuffer();
        sb.append(generatorYMDHMSS());
        sb.append(RandomUtil.randomString(3));
        return sb.toString();
    }

    public static String generatorStreamNo(){
        StringBuffer sb = new StringBuffer();
        sb.append(generatorYMDHMSS());
        sb.append(RandomUtil.randomNumbers(6));
        return sb.toString();
    }

    private static class Variant {
        private long sequence = 1;
        private long lastTimestamp = -1;
    }

}
